import 'dart:async';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:sonora/config/sj_config.dart';
import 'package:sonora/models/sj_login_response_data.dart';
import 'package:sonora/network/sj_network.dart';
import 'package:sonora/services/sj_api_log_paths.dart';
import 'package:sonora/utils/sj_device_utils.dart';
import 'package:sonora/utils/sj_storage_utils.dart';
import 'package:sonora/utils/sj_utils.dart';

/// 打点请求头key统一传参
class SjLogHeadersKey{
  static const String sjData = "data";
  static const String sjLogType = "log_type";
  static const String sjSubtype = "subtype";
  static const String sjBehavior = "behavior";
  static const String sjDeviceId = "device-id";
  static const String sjAndroidId = "android_id";
  static const String sjUserId = "user_id";
  static const String sjPkg = "pkg";
  static const String sjChnId = "chn_id";
  static const String sjVer = "ver";
  static const String sjPlatform = "platform";
  static const String sjModel = "model";
  static const String sjPVer = "p_ver";
  static const String sjLanId = "lan_id";
  static const String sjSecId = "sec_id";
  static const String sjUtmSource = "utm_source";
  static const String sjAfAdgroupId = "af_adgroup_id";
  static const String sjAfAdset = "af_adset";
  static const String sjAfAdsetId = "af_adset_id";
  static const String sjAfStatus = "af_status";
  static const String sjAfAgency = "af_agency";
  static const String sjAfChannel = "af_channel";
  static const String sjAfCampaign = "campaign";
  static const String sjAfCampaignId = "campaign_id";
  static const String sjCountry = "country";
  static const String sjsysLan = "sys_lan";
}

/// 打点中所有涉及到的页面KEY
class SjLogPages {
  /*
  page -- ’launch‘
    1. 快速登录，page -- 'quicklogin'
  2. 苹果登录，page -- 'applelogin'
  3. 用户协议，page -- 'terms'
  4. 隐私协议，page -- 'privacy'
  5. 登录成功 ，page -- 'loginsuccess'
  */
  static const String sjPageNamelaunch = "launch";
  static const String sjPageNameQuicklogin = "quicklogin";
  static const String sjPageNameApplelogin = "applelogin";
  static const String sjPageNameTerms = "terms";
  static const String sjPageNamePrivacy = "privacy";
  static const String sjPageNameLoginsuccess = "loginsuccess";
  static const String sjPageNameHomeTab = "homeTab";
  static const String sjPageNameVideoTab = "videoTab";
  static const String sjPageNameMedalTab = "medalTab";
  static const String sjPageNameMineTab = "mineTab";

  /*
  3. 各主tab点击事件埋点
4. 内购埋点
  1. 打开充值页面，page -- 'purchase'
  2. 创建内购订单，page -- 'createorder'
5. 我的埋点
  1. 编辑头像，page -- 'editavatar'
  2. 退出登录，page -- 'logout'
  3. 删除账号，page -- 'deleteaccount'
  4. 点击客服，page -- 'customer'
6. 其它
  1. 举报，page -- 'report'
  2. 拉黑，page -- 'block'
   */

  static const String sjActionNamePurchase = "purchase";
  static const String sjActionNameCreateorder = "createorder";
  static const String sjActionNameEditavatar = "editavatar";
  static const String sjActionNameLogout = "logout";
  static const String sjActionNameDeleteaccount = "deleteaccount";
  static const String sjActionNameCustomer = "customer";
  static const String sjActionNameReport = "report";
  static const String sjActionNameBlock = "block";
  
}

class SjLogPvManger {
  SjLogPvManger._();

  static const String _sjevent = 'event';
  static const String _sjtm = 'tm';
  static const String _sjpage = 'page';
  static const String _sjsubPage = 'subPage';
  static const String _sjterPage = 'terPage';
  static const String _sjbroadcasterId = 'broadcasterId';
  static const String _sjduration = 'duration';

  static void stat({
    String? page,
    String? subPage,
    String? terPage,
    String? broadcasterId,
  }) {
    var map = <String, dynamic>{};
    // ⚠️page传入下方的埋点事件page值
    if (page != null) {
      map[_sjpage] = page;
    }
    if (subPage != null) {
      map[_sjsubPage] = subPage;
    }
    if (terPage != null) {
      map[_sjterPage] = terPage;
    }
    if (broadcasterId != null) {
      map[_sjbroadcasterId] = broadcasterId;
    }
    map[_sjduration] = 0;
    map[_sjevent] = 'pv';
    map[_sjtm] = DateTime.now().millisecondsSinceEpoch;
    SjLogManger().putLog(SjLogType.globalBehavior, map);
  }
}

enum SjLogType {
  globalBehavior('event', 'global_behavior', 'event'),
  clickEvent("event", "click", "event");

  final String sjLogType;
  final String sjSubType;
  final String sjBehavior;

  const SjLogType(this.sjLogType, this.sjSubType, this.sjBehavior);
}

class SjLogManger {
  static final SjLogManger _instance = SjLogManger._internal();
  factory SjLogManger() {
    return _instance;
  }
  SjLogManger._internal();

  static const String tag = "LogManger"; // 日志标签
  static const int limitSize = 20; // 打点任务最多缓存长度
  static int _serialId = 0;
  // 每次启动App该值会修改
  static String launcherId =
      '${DateTime.now().millisecondsSinceEpoch}';
  final List<Map<String, dynamic>> cacheList = [];
  bool _isWaitingForSend = false; // 是否需要延迟上报
  

  /// 上报日志
  Future<void> putLog(SjLogType logType, Map<String, dynamic>? event) async {
    if (logType.sjLogType.isEmpty ||
        logType.sjSubType.isEmpty ||
        logType.sjBehavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.sjLogType, logType.sjSubType, logType.sjBehavior, event);
    cacheList.insert(0, itemData);
    sendDelayed();
  }

  /// 延时发送日志
  void sendDelayed() {
    if (_isWaitingForSend) {
      return;
    }
    _isWaitingForSend = true;
    Timer(const Duration(milliseconds: 2000), () {
      _isWaitingForSend = false;
      sendLog(false);
    });
  }

  /// 发日志打点
  void sendLog(bool forceUploadAll) {
    try {
      List<Map<String, dynamic>> sendList = [];
      if (cacheList.isEmpty) {
        return;
      } else if (cacheList.length >= limitSize && !forceUploadAll) {
        sendList.addAll(cacheList.sublist(0, limitSize));
        cacheList.removeRange(0, limitSize);
      } else {
        sendList.addAll(cacheList);
        cacheList.clear();
      }
      _doUpload(sendList, true);
    } catch (e) {
    }
  }

  /// 立马发送日志
  Future<void> putLogRightNow(SjLogType logType, Map<String, dynamic>? event) async {
    if (logType.sjLogType.isEmpty ||
        logType.sjSubType.isEmpty ||
        logType.sjBehavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.sjLogType, logType.sjSubType, logType.sjBehavior, event);
    List<Map<String, dynamic>> list = [];
    list.add(itemData);

    _doUpload(list, false);
  }

  /// 执行上传
  Future<void> _doUpload(
      List<Map<String, dynamic>> sendList, bool isContinue) async {
    // HBRequestUntil.request(HBRequestType.hbEnumPost,hbGlobalLogUrl,newHost: hbLogBaseRequestUrl,requestParam:sendList,isShowLoading: false, (data){
    //   if(isContinue) {
    //      sendDelayed();
    //   }
    // }, (error) {
    // });

    try {
        Dio dio = SjNetwork().clientDio;
        var response = await dio.post('$biHttpHost${SjApiLogPaths.logLiveChat}', data: sendList);
        if (response.data != null && response.data['data'] != null) {
          if (isContinue) sendDelayed();
        }
      } catch (e) {
      }
  }

  Future<Map<String, dynamic>> _buildItemData(String logType, String subType,
      String behavior, Map<String, dynamic>? event) async {
    String? udid = await SjDeviceUtils.getUdid();
    SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId;
    String? country;
    if (loginData != null) {
      userId = loginData.userInfo?.userId;
      country = loginData.userInfo?.country;
    }
    Map<String, dynamic> itemData = {};
    itemData[SjLogHeadersKey.sjData] = [event];
    itemData[SjLogHeadersKey.sjLogType] = 'event';
    itemData[SjLogHeadersKey.sjSubtype] = 'global_behavior';
    itemData[SjLogHeadersKey.sjBehavior] = 'event';
    itemData[SjLogHeadersKey.sjDeviceId] = udid ?? '';
    itemData[SjLogHeadersKey.sjUserId] = userId ?? '';
    itemData[SjLogHeadersKey.sjPkg] = await SjDeviceUtils.getPackageName();
    itemData[SjLogHeadersKey.sjChnId] = '';
    itemData[SjLogHeadersKey.sjVer] = await SjDeviceUtils.getAppVersion();
    itemData[SjLogHeadersKey.sjPlatform] = await SjDeviceUtils.getPlatform();
    itemData[SjLogHeadersKey.sjModel] = await SjDeviceUtils.getDeviceModel();
    itemData[SjLogHeadersKey.sjPVer] = await SjDeviceUtils.getBuildNumber();
    itemData[SjLogHeadersKey.sjLanId] = SjUtils.strMD5("$launcherId${udid ?? ''}");
    itemData[SjLogHeadersKey.sjSecId] = _serialId++;
    itemData[SjLogHeadersKey.sjsysLan] = SjDeviceUtils.getSystemLanguage();
    itemData[SjLogHeadersKey.sjCountry] = country ?? '';
    itemData["tm"] = DateTime.now().millisecondsSinceEpoch;
    return itemData;
  }
}